﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace SwiftMVVM.ChangeTracking
{
    /// <summary>
    /// The object change notes the object and the value it had prior to the change.
    /// We use this to revert the last value for a given object, as well as 
    /// to report on what changes have been made to an object over time.
    /// </summary>
    public sealed class ChangeDetail
    {
        /// <summary>
        /// A reference to the object that changed
        /// </summary>
        public INotifyPropertyChanged ObjectThatChanged { get; private set; }

        /// <summary>
        /// The value of the property prior to the change
        /// </summary>
        public object Value { get; private set; }

        /// <summary>
        /// The value of the property prior to the change
        /// </summary>
        public object PriorValue { get; internal set; }

        /// <summary>
        /// The name of the property that changed
        /// </summary>
        public string Property { get; private set; }

        /// <summary>
        /// This is a readonly property, it should not show up in undo/redo lists
        /// </summary>
        public bool IsReadOnly { get; private set; }

        /// <summary>
        /// Copy Constructor for Change Differential
        /// </summary>
        /// <param name="differential"></param>
        internal ChangeDetail(ChangeDetail differential)
            : this(differential.ObjectThatChanged, differential.Property,
            differential.Value, differential.PriorValue, differential.IsReadOnly) { }

        /// <summary>
        /// Constructs a new change differential
        /// </summary>
        /// <param name="objectThatChanged">The object that changed</param>
        /// <param name="propertyName">The name of the property that changed</param>
        /// <param name="value">The value of the property that changed</param>
        /// <param name="priorValue">The prior value of the object</param>
        internal ChangeDetail(INotifyPropertyChanged objectThatChanged, string propertyName, object value, object priorValue, bool isReadOnly)
        {
            this.ObjectThatChanged = objectThatChanged;
            this.Value = value;
            this.Property = propertyName;
            this.PriorValue = priorValue;
            this.IsReadOnly = isReadOnly;
        }

        public override string ToString()
        {
            return string.Format(string.Format("Object: {0}, Property: {1}, Prior: {2}, New: {3}, Readonly {4}",
                this.ObjectThatChanged.GetType().Name,
                this.Property,
                this.PriorValue.ToString(),
                this.Value.ToString(),
                this.IsReadOnly));
        }
    }
}
